前幾天做了個簡單的小小遊戲:玩家在 TabPageTwoVC 上與電腦廝殺,雙方初始生命值都是 210 。玩家攻擊一次電腦會減少 30 生命值,電腦攻擊一次的效果則是 1~60 的隨機數值。雙方每回合剩下的生命值則要回傳到主頁 TabPageOneVC ,並比較輸贏。
為了達到遊戲效果,我們必須讓玩家與電腦每回合剩下的生命值即時顯示到 TabPageOneVC 上,並比較生命值高低。如圖
原本考慮用比較熟悉的 delegate 方式來實現不同 VC 之間傳值,不過 delegate 偏向物件對物件之間的溝通。後來決定試試新的 Notification 作法。
參考了許多教學文(也小小撞壁了兩天),終於還是完成了:
Notification
NotificationCenter.default.addObserver
NotificationCenter.default.addObserver(observer: Any, selector: 傳值的方法, name: NSNotification.Name(rawValue: key 的名稱), object: Any?)
想像一下在我們的 TabPageTwoVC 與 TabPageOneVC,想要私下熱線。這時候,我們必須決定要兩個 VC 的哪些物件上,安裝一組電話。
在這個小遊戲裡頭,就是我們在 TabPageTwoVC 的 attack 按鈕,做為生命值的發送者 ; 以及 TabPageOneVC 上的 Game1 Player 與 Game1 CPU 兩個 label。
為了達到這個秘密熱線,我們首先要為 TabPageTwoVC 上,顯示玩家與電腦生命值 label 分別註冊一個獨一無二的 key(我自己是把他想像成是一組類似電話號碼的字串,讓擁有這個 key 的兩個物件可以互相撥打熱線) 。
使用 NotificationCenter.default.addObserver ,添加 addObserver 在我們要監聽的物件上。
NotificationCenter.default.addObserver(self, selector: #selector(passMyGameOneScoreData(myLife:)), name: NSNotification.Name(rawValue: gameOneBmooScoreKey), object: nil)
///#selector(passMyGameOneScoreData(myLife:) 是一個 func
//rawValue 的值是我們剛剛註冊的那個 key
NotificationCenter.default.post(name: NSNotification.Name(rawValue: gameOneBmooScoreKey), object: self, userInfo: ["me": "\(String(describing: myLifeVal.text!))"])
// userInfo 的param: [AnyHashable : Any] 拿來把我們想 pass 的 data 儲存成一個 dictionary
接下來開始在接收訊息的 VC: TabPageOneVC 上添加電話(addObserver),以便接起來自 TabPageTwoVC 的熱線。
在 viewDidLoad() 裡面插入 addObserver :
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: gameOneBmooScoreKey), object: nil, queue: nil, using: catchGameOneMyNotification)
定義 catchGameOneMyNotification 這個 func :
func catchGameOneMyNotification(notification:Notification) -> Void {
guard let score = notification.userInfo!["me"] else { return }
print(score)
gameOnePlayerScore.text = score as! String
}
即可完成即時傳值的功能!